home *** CD-ROM | disk | FTP | other *** search
/ Aminet 6 / Aminet 6 - June 1995.iso / Aminet / gfx / 3d / irit50src.lha / irit5 / symb_lib / multires.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-30  |  22.5 KB  |  592 lines

  1. /*****************************************************************************
  2. *   A decomposition of a Bspline curve into multi resolution hierarchy.      *
  3. *                                         *
  4. * Written by:  Gershon Elber                Ver 0.1, June 1993.  *
  5. *****************************************************************************/
  6.  
  7. #include "irit_sm.h"
  8. #include "cagd_lib.h"
  9. #include "symb_loc.h"
  10.  
  11. #define MAX_AFFECTED_DIST 4.0
  12.  
  13. /*****************************************************************************
  14. * DESCRIPTION:                                                               M
  15. * Given a Bspline curve, computes a hierarch of Bspline curves, each being   M
  16. * represented using a subspace of the previous, upto a curve with no         M
  17. * interior knots (i.e. a polynomial Bezier).                     M
  18. *   However, if Discont == TRUE, then C1 discontinuities are preserved         M
  19. * through out the hierarchy decomposition.                     M
  20. *   Each level in hierarchy has approximately half the number of control     M
  21. * points of the previous one.                             M
  22. *   Least square curve fitting is used to build the hierarchy.             M
  23. *                                                                            *
  24. * PARAMETERS:                                                                M
  25. *   Crv:       To compute a least square multi resolution decomposition for. M
  26. *   Discont:   Do we want to preserve discontinuities?                       M
  27. *                                                                            *
  28. * RETURN VALUE:                                                              M
  29. *   SymbMultiResCrvStruct *:   A multi resolution curve structure hold the   M
  30. *                              multi resolution decomposition of Crv.        M
  31. *                                                                            *
  32. * KEYWORDS:                                                                  M
  33. *   SymbCrvMultiResDecomp, multi resolution, least square decomposition      M
  34. *****************************************************************************/
  35. SymbMultiResCrvStruct *SymbCrvMultiResDecomp(CagdCrvStruct *Crv, int Discont)
  36. {
  37.     CagdBType
  38.     Periodic = CAGD_IS_PERIODIC_CRV(Crv);
  39.     int KVListSize, *KVListSizes, i, j,
  40.     Length = Crv -> Length,
  41.     PrevLen = CAGD_CRV_PT_LST_LEN(Crv),
  42.     Order = Crv -> Order,
  43.     KVMaxSize = CAGD_CRV_PT_LST_LEN(Crv) + Order;
  44.     CagdRType **KVList, *KVPtr, *Params,
  45.     *KVPrev = Crv -> KnotVector;
  46.     SymbMultiResCrvStruct *MRCrv;
  47.     CagdCrvStruct *OCrv;
  48.  
  49.     if (!CAGD_IS_BSPLINE_CRV(Crv)) {
  50.     SYMB_FATAL_ERROR(SYMB_ERR_BSP_CRV_EXPECT);
  51.     return NULL;
  52.     }
  53.  
  54.     /* Compute the hierarchy size and allocate its KnotVectors. */
  55.     for (KVListSize = 0; (1 << KVListSize) < PrevLen - Order; KVListSize++);
  56.     KVList = (CagdRType **) IritMalloc(sizeof(CagdRType *) * ++KVListSize);
  57.     KVListSizes = (int *) IritMalloc(sizeof(int) * KVListSize);
  58.  
  59.     KVList[0] = (CagdRType *) IritMalloc(sizeof(CagdRType) * KVMaxSize);
  60.     KVListSizes[0] = KVMaxSize;
  61.     SYMB_GEN_COPY(KVList[0], KVPrev, sizeof(CagdRType) * KVMaxSize);
  62.     
  63.     for (i = 1; i < KVListSize; i++) {
  64.     KVPtr = KVList[i] = (CagdRType *)
  65.                 IritMalloc(sizeof(CagdRType) * KVMaxSize);
  66.  
  67.     /* Copy first Order knots verbatim. */
  68.     KVListSizes[i] = 2 * Order; /* End conditions are copied verbatim. */
  69.     for (j = 0; j < Order; j++)
  70.         *KVPtr++ = *KVPrev++;
  71.  
  72.     /* Skip every second interior knot. */
  73.     for (; j < PrevLen; j++, KVPrev++) {
  74.         if (Discont) {
  75.         if ((j & 0x01) == 0 ||
  76.             APX_EQ(KVPrev[-1], KVPrev[0]) ||
  77.             APX_EQ(KVPrev[0], KVPrev[1])) {
  78.             *KVPtr++ = *KVPrev;
  79.             KVListSizes[i]++;
  80.         }
  81.         }
  82.         else {
  83.         if ((j & 0x01) == 0) {
  84.             *KVPtr++ = *KVPrev;
  85.             KVListSizes[i]++;
  86.         }
  87.         }
  88.     }
  89.  
  90.     /* Copy last Order knots verbatim. */
  91.     for (j = 0; j < Order; j++)
  92.         *KVPtr++ = *KVPrev++;
  93.  
  94.     KVPrev = KVList[i];
  95.     PrevLen = KVListSizes[i] - Order;
  96.  
  97.     /* Make sure we did not exhaust all the interior knots already, or  */
  98.     /* alternatively all interior knots maintains discontonuities.      */
  99.     if (Periodic ? PrevLen <= Order + Order - 1 : PrevLen <= Order) {
  100.         KVListSize -= (KVListSize - i) - 1;
  101.         if (Periodic ? PrevLen < Order + Order - 1 : PrevLen < Order) {
  102.         IritFree(KVList[i]);
  103.         KVListSize--;
  104.         }
  105.         break;
  106.     }
  107.     else if (KVListSizes[i] == KVListSizes[i-1]) {
  108.         KVListSize -= KVListSize - i;
  109.         IritFree(KVList[i]);
  110.         break;
  111.     }
  112.     }
  113.  
  114.     if (Periodic) {
  115.     /* Make sure spaces are consistent at the ends. */
  116.     for (i = 0; i < KVListSize; i++) {
  117.         int Len = KVListSizes[i] - Order;
  118.         CagdRType
  119.         *KV = KVList[i];
  120.  
  121.         for (j = 0; j < Order - 1; j++)
  122.         KV[j] = KV[Order - 1] + KV[Len + j - (Order - 1)]
  123.                       - KV[Len];
  124.         for (j = Len + 1; j < Len + Order; j++)
  125.         KV[j] = KV[Len] + KV[j - Len + Order - 1] - KV[Order - 1];
  126.     }
  127.     }
  128.  
  129. #ifdef DEBUG_PRINT_KVS
  130.     for (i = 0; i < KVListSize; i++) {
  131.     fprintf(stderr, "KV - LEVEL %d (len = %d) ***********************\n",
  132.         i, KVListSizes[i]);
  133.  
  134.     for (j = 0; j < KVListSizes[i]; j++)
  135.         fprintf(stderr, "%0.7lf ", KVList[i][j]);
  136.     fprintf(stderr, "\n\n");
  137.     }
  138. #endif /* DEBUG_PRINT_KVS */
  139.  
  140.     /* Now compute the curves in reverse, from the smallest subspace to the */
  141.     /* largest and accumulate the representation upto the original space.   */
  142.     Params = CagdCrvNodes(Crv);
  143.     MRCrv = SymbCrvMultiResNew(KVListSize, Periodic);
  144.  
  145.     if (!BspCrvHasOpenEC(Crv)) { /* We need an open end version of the curve. */
  146.     if (Periodic) {
  147.         CagdCrvStruct
  148.         *TCrv = CnvrtPeriodic2FloatCrv(Crv);
  149.  
  150.         OCrv = CnvrtFloat2OpenCrv(TCrv);
  151.         CagdCrvFree(TCrv);
  152.     }
  153.     else {
  154.         OCrv = CnvrtFloat2OpenCrv(Crv);
  155.     }
  156.     }
  157.     else
  158.     OCrv = CagdCrvCopy(Crv);
  159.  
  160.     for (i = KVListSize - 1; i >= 0; i--) {
  161.     CagdCrvStruct *InterpCrv, *DiffCrv;
  162.     CagdCtlPtStruct
  163.         *PtList = NULL;
  164.  
  165.     /* Sample the current curve at its node values to guarantee a       */
  166.     /* unique interpolatory result - identical to the original curve.   */
  167.     for (j = CAGD_CRV_PT_LST_LEN(OCrv) - 1; j >= 0; j--) {
  168.         CagdCtlPtStruct
  169.         *Pt = CagdCtlPtNew(OCrv -> PType);
  170.         CagdRType
  171.         *R = BspCrvEvalAtParam(OCrv, Params[j]);
  172.  
  173.         SYMB_GEN_COPY(Pt -> Coords, R,
  174.               sizeof(CagdRType) * CAGD_MAX_PT_SIZE);
  175.  
  176.         Pt -> Pnext = PtList;
  177.         PtList = Pt;
  178.     }
  179.  
  180.     InterpCrv = BspCrvInterpolate(PtList, Length, Params, KVList[i],
  181.                       KVListSizes[i] - Order -
  182.                           (Periodic ? Order - 1 : 0),
  183.                       Order, Periodic);
  184.     CagdCtlPtFreeList(PtList);
  185.  
  186.     if (!BspCrvHasOpenEC(InterpCrv)) {
  187.         CagdCrvStruct *OInterpCrv;
  188.  
  189.         if (Periodic) {
  190.         CagdCrvStruct
  191.             *TCrv = CnvrtPeriodic2FloatCrv(InterpCrv);
  192.  
  193.         OInterpCrv = CnvrtFloat2OpenCrv(TCrv);
  194.         CagdCrvFree(TCrv);
  195.         }
  196.         else {
  197.         OInterpCrv = CnvrtFloat2OpenCrv(InterpCrv);
  198.         }
  199.  
  200.         DiffCrv = SymbCrvSub(OCrv, OInterpCrv);
  201.         MRCrv -> HieCrv[KVListSize - 1 - i] = OInterpCrv;
  202.         CagdCrvFree(InterpCrv);
  203.     }
  204.     else {
  205.         DiffCrv = SymbCrvSub(OCrv, InterpCrv);
  206.         MRCrv -> HieCrv[KVListSize - 1 - i] = InterpCrv;
  207.     }
  208.  
  209.     CagdCrvFree(OCrv);
  210.     OCrv = DiffCrv;
  211.     }
  212.  
  213.     CagdCrvFree(OCrv);
  214.     IritFree((VoidPtr) Params);
  215.  
  216.     return MRCrv;
  217. }
  218.  
  219. /*****************************************************************************
  220. * DESCRIPTION:                                                               M
  221. * Given a multi resolution decomposition of a Bspline curve, computes the    M
  222. * regular Bspline curve out of it.                         *
  223. *                                                                            M
  224. *                                                                            *
  225. * PARAMETERS:                                                                M
  226. *   MRCrv:    A multi resolution decomposition of a curve.                   M
  227. *                                                                            *
  228. * RETURN VALUE:                                                              M
  229. *   CagdCrvStruct *:  A curve that adds up all components of the multi       M
  230. *                     resolution decomposition MRCrv.                        M
  231. *                                                                            *
  232. * KEYWORDS:                                                                  M
  233. *   SymbCrvMultiResCompos, multi resolution, least square decomposition      M
  234. *****************************************************************************/
  235. CagdCrvStruct *SymbCrvMultiResCompos(SymbMultiResCrvStruct *MRCrv)
  236. {
  237.     return SymbCrvMultiResComposAtT(MRCrv,
  238.                     MRCrv -> Levels - 1 +
  239.                     (MRCrv -> RefineLevel != FALSE));
  240. }
  241.  
  242. /*****************************************************************************
  243. * DESCRIPTION:                                                               M
  244. * Given a multi resolution decomposition of a Bspline curve, computes a      M
  245. * regular Bspline curve out of it representing the decomposed curve at       M
  246. * the multi resolution hierarchy level of T.                     M
  247. *   Although decomposition is discrete, T can be any real number between     M
  248. * these discrete levels and a linear interpolation of adjacent levels is     M
  249. * exploited.                                     M
  250. *                                                                            *
  251. * PARAMETERS:                                                                M
  252. *   MRCrv:     A multi resolution decomposition of a curve.                  M
  253. *   T:         A mult resolution hierarcy level to compute curve for.        M
  254. *                                                                            *
  255. * RETURN VALUE:                                                              M
  256. *   CagdCrvStruct *:  A curve that adds up all components of the multi       M
  257. *                     resolution decomposition MRCrv up to and including     M
  258. *                     level T.                                               M
  259. *                                                                            *
  260. * KEYWORDS:                                                                  M
  261. *   SymbCrvMultiResComposAtT, multi resolution, least square decomposition   M
  262. *****************************************************************************/
  263. CagdCrvStruct *SymbCrvMultiResComposAtT(SymbMultiResCrvStruct *MRCrv,
  264.                     CagdRType T)
  265. {
  266.     int i,
  267.     It = (int) T;
  268.     CagdCrvStruct
  269.     *SumCrv = CagdCrvCopy(MRCrv -> HieCrv[0]);
  270.  
  271.     for (i = 1;
  272.      i <= It && i < MRCrv -> Levels + (MRCrv -> RefineLevel != FALSE);
  273.      i++) {
  274.     CagdCrvStruct
  275.         *TCrv = SymbCrvAdd(SumCrv, MRCrv -> HieCrv[i]);
  276.  
  277.     CagdCrvFree(SumCrv);
  278.     SumCrv = TCrv;
  279.     }
  280.  
  281.     if (It != T) {
  282.     CagdCrvStruct
  283.         *TCrv1 = SymbCrvScalarScale(MRCrv -> HieCrv[It + 1], T - It),
  284.         *TCrv2 = SymbCrvAdd(SumCrv, TCrv1);
  285.  
  286.     CagdCrvFree(TCrv1);
  287.     CagdCrvFree(SumCrv);
  288.     SumCrv = TCrv2;
  289.     }
  290.  
  291.     return SumCrv;
  292. }
  293.  
  294. /*****************************************************************************
  295. * DESCRIPTION:                                                               M
  296. * Given a multi resolution decomposition of a Bspline curve, edit it by      M
  297. * modifying its Level'th Level according to the TransDir of Position at      M
  298. * parametr t.                                      M
  299. *   Level can be a fraction number between the discrete levels of the        M
  300. * decomposition denoting a linear blend of two neighboring discrete levels.  M
  301. *   Editing is performed in place.                         M
  302. *                                                                            *
  303. * PARAMETERS:                                                                M
  304. *   MRCrv:       A multi resolution decomposition of a curve to edit it in   M
  305. *                place.                                 M
  306. *   t:           Parameter value at which to modify MRCrv.                   M
  307. *   TransDir:    Directional tranlation transformation to apply.             M
  308. *   Level:       Of multi resolution hierarchy to edit.                      M
  309. *   FracLevel:   The fraction level to edit - will blend two neighboring     M
  310. *         levels.                             M
  311. *   SpanDiscont: Are we allowed to cross over discontinuities?             M
  312. *                                                                            *
  313. * RETURN VALUE:                                                              M
  314. *   void                                                                     M
  315. *                                                                            *
  316. * KEYWORDS:                                                                  M
  317. *   SymbCrvMultiResEdit, multi resolution, least square decomposition        M
  318. *****************************************************************************/
  319. void SymbCrvMultiResEdit(SymbMultiResCrvStruct *MRCrv,
  320.              CagdRType t,
  321.              CagdVType TransDir,
  322.              CagdRType Level,
  323.              CagdRType FracLevel)
  324. {
  325.     int ILevel = (int) Level;
  326.  
  327.     if (Level == ILevel) {
  328.     CagdCrvStruct *Crv, *OrigCrv, *DiffCrv;
  329.     CagdRType *BasisFuncs, **Points;
  330.     int i, Length, Order, IndexFirst;
  331.  
  332.     if (ILevel < 0 ||
  333.         ILevel >= MRCrv -> Levels + (MRCrv -> RefineLevel != FALSE)) {
  334.         SYMB_FATAL_ERROR(SYMB_ERR_OUT_OF_RANGE);
  335.         return;
  336.     }
  337.  
  338.     /* Prepare the Level'th curve in the hierarchy. */
  339.     OrigCrv = CagdCrvCopy(MRCrv -> HieCrv[0]);
  340.     for (i = 1; i <= ILevel; i++) {
  341.         CagdCrvStruct
  342.         *TCrv = SymbCrvAdd(OrigCrv, MRCrv -> HieCrv[i]);
  343.  
  344.         CagdCrvFree(OrigCrv);
  345.         OrigCrv = TCrv;
  346.     }
  347.     Crv = CagdCrvCopy(OrigCrv);
  348.  
  349.     Points = Crv -> Points;
  350.     Length = Crv -> Length;
  351.     Order = Crv -> Order;
  352.  
  353.     BasisFuncs = BspCrvCoxDeBoorBasis(Crv -> KnotVector, Order,
  354.                       Length +
  355.                           (Crv -> Periodic ? Order - 1 : 0),
  356.                       t, &IndexFirst);
  357.  
  358.     for (i = IndexFirst; i < IndexFirst + Order; i++) {
  359.         CagdRType
  360.         MultFactor = BasisFuncs[i - IndexFirst];
  361.  
  362.         switch (Crv -> PType) {
  363.             case CAGD_PT_E3_TYPE:
  364.                 Points[3][i] += TransDir[2] * MultFactor;
  365.         case CAGD_PT_E2_TYPE:
  366.                 Points[2][i] += TransDir[1] * MultFactor;
  367.                 Points[1][i] += TransDir[0] * MultFactor;
  368.             break;
  369.         case CAGD_PT_P3_TYPE:
  370.         case CAGD_PT_P2_TYPE:
  371.             fprintf(stderr, "RATIONALS NOT SUPPORTED\n");
  372.             exit(1);
  373.             break;
  374.         default:
  375.             SYMB_FATAL_ERROR(SYMB_ERR_UNSUPPORT_PT);
  376.             break;
  377.         }
  378.     }
  379.  
  380.     /* Construct the new hierarchy. */
  381.     DiffCrv = SymbCrvSub(Crv, OrigCrv);
  382.     CagdCrvFree(OrigCrv);
  383.     CagdCrvFree(Crv);
  384.  
  385.     /* Apply the fraction ratio, if necessary. */
  386.     if (!APX_EQ(FracLevel, 1.0)) {
  387.         Crv = SymbCrvScalarScale(DiffCrv, FracLevel);
  388.         CagdCrvFree(DiffCrv),
  389.         DiffCrv = Crv;
  390.     }
  391.  
  392.     Crv = SymbCrvAdd(MRCrv -> HieCrv[ILevel], DiffCrv);
  393.     CagdCrvFree(MRCrv -> HieCrv[ILevel]);
  394.     MRCrv -> HieCrv[ILevel] = Crv;
  395.  
  396.     CagdCrvFree(DiffCrv);
  397.     }
  398.     else {
  399.     int Level1 = ILevel,
  400.         Level2 = Level1 + 1;
  401.  
  402.     FracLevel = Level - Level1;
  403.  
  404.     SymbCrvMultiResEdit(MRCrv, t, TransDir, Level1,
  405.                 1.0 - FracLevel),
  406.     SymbCrvMultiResEdit(MRCrv, t, TransDir, Level2, FracLevel);
  407.     }
  408. }
  409.  
  410. /*****************************************************************************
  411. * DESCRIPTION:                                                               M
  412. * Given a multi resolution decomposition of a Bspline curve, refine it at    M
  413. * neighborhood of parameter value t, in place.                     M
  414. *                                                                            *
  415. * PARAMETERS:                                                                M
  416. *   MRCrv:       A multi resolution decomposition of a curve, to refine in   M
  417. *                place.                                 M
  418. *   T:           Parameter value at which to refine MRCrv.                   M
  419. *   SpanDiscont: Do we want to refine beyond discontinuities?                M
  420. *                                                                            *
  421. * RETURN VALUE:                                                              M
  422. *   CagdRType *:  A pointer to an array of two real numbers holding the      M
  423. *                 domain in MRCrv that was refined.                 M
  424. *                                                                            *
  425. * KEYWORDS:                                                                  M
  426. *   SymbCrvMultiResRefineLevel, multi resolution, least square decomposition M
  427. *****************************************************************************/
  428. CagdRType *SymbCrvMultiResRefineLevel(SymbMultiResCrvStruct *MRCrv,
  429.                       CagdRType T,
  430.                       int SpanDiscont)
  431. {
  432.     static CagdRType Domain[2];
  433.     CagdCrvStruct *Crv, *RefCrv;
  434.     CagdRType TMin, TMax, **Points, *KV, *NewKV;
  435.     int i, j, Order, Length, LastLIndex, FirstGIndex, StartIndex,
  436.     NewKVIndex = 0;
  437.  
  438.     if (!MRCrv -> RefineLevel) {
  439.     /* Do not have a refining level yet - add a zero valued curve now. */
  440.     Crv = MRCrv -> HieCrv[MRCrv -> Levels] =
  441.         CagdCrvCopy(MRCrv -> HieCrv[MRCrv -> Levels - 1]);
  442.     Points = Crv -> Points;
  443.     for (j = 0; j < Crv -> Length; j++)
  444.         for (i = 1; i <= CAGD_NUM_OF_PT_COORD(Crv -> PType); i++)
  445.         Points[i][j] = 0.0;
  446.     MRCrv -> RefineLevel = TRUE;
  447.     }
  448.     else {
  449.     Crv = MRCrv -> HieCrv[MRCrv -> Levels];
  450.     }
  451.     Length = Crv -> Length;
  452.     Order = Crv -> Order;
  453.  
  454.     /* Figure out the knots to insert to the refining curve. */
  455.     KV = Crv -> KnotVector;
  456.     NewKV = (CagdRType *) IritMalloc(sizeof(CagdRType) * (Order + 1) * 2);
  457.     CagdCrvDomain(Crv, &TMin, &TMax);
  458.     LastLIndex = BspKnotLastIndexL(KV, Length + Order, T);
  459.     FirstGIndex = BspKnotFirstIndexG(KV, Length + Order, T);
  460.  
  461.     /* Compute the new knots to the left. */
  462.     for (StartIndex = 0, i = MAX(0, LastLIndex - Order);
  463.      i <= LastLIndex;
  464.      i++) {
  465.     if (!APX_EQ(KV[i], KV[i + 1]))
  466.         NewKV[NewKVIndex++] = (KV[i] + KV[i + 1]) / 2.0;
  467.     else if (SpanDiscont)
  468.         StartIndex = NewKVIndex;
  469.     }
  470.     /* Compute the new knots to the right. */
  471.     for (i = FirstGIndex; i < MIN(FirstGIndex + Order, Length + Order); i++) {
  472.     if (!APX_EQ(KV[i], KV[i + 1]))
  473.         NewKV[NewKVIndex++] = (KV[i] + KV[i + 1]) / 2.0;
  474.     else if (SpanDiscont)
  475.         break;
  476.     }
  477.  
  478. #ifdef DEBUG_REFINE_KNOTS
  479.     fprintf(stderr, "\nOld knot vector ********************\n");
  480.     for (i = 0; i < Length + Order; i++)
  481.     fprintf(stderr, "%8lg  ", KV[i]);
  482.     fprintf(stderr, "\nNew knots **************************\n");
  483.     for (i = StartIndex; i < NewKVIndex; i++)
  484.     fprintf(stderr, "%8lg  ", NewKV[i]);
  485. #endif /* DEBUG_REFINE_KNOTS */
  486.  
  487.     Domain[0] = NewKV[StartIndex];
  488.     Domain[1] = NewKV[NewKVIndex - 1];
  489.     RefCrv = CagdCrvRefineAtParams(Crv, FALSE, &NewKV[StartIndex],
  490.                    NewKVIndex - StartIndex);
  491.     IritFree((VoidPtr) NewKV);
  492.  
  493.     CagdCrvFree(MRCrv -> HieCrv[MRCrv -> Levels]);
  494.     MRCrv -> HieCrv[MRCrv -> Levels] = RefCrv;
  495.  
  496.     return Domain;
  497. }
  498.  
  499. /*****************************************************************************
  500. * DESCRIPTION:                                                               M
  501. * Given a multi resolution decomposition of a Bspline curve, free it.        M
  502. *                                                                            *
  503. * PARAMETERS:                                                                M
  504. *   MRCrv:       A multi resolution decomposition of a curve to free.        M
  505. *                                                                            *
  506. * RETURN VALUE:                                                              M
  507. *   void                                                                     M
  508. *                                                                            *
  509. * KEYWORDS:                                                                  M
  510. *   SymbCrvMultiResFree, multi resolution, least square decomposition         M
  511. *****************************************************************************/
  512. void SymbCrvMultiResFree(SymbMultiResCrvStruct *MRCrv)
  513. {
  514.     int i;
  515.  
  516.     if (MRCrv == NULL)
  517.     return;
  518.  
  519.     for (i = 0; i < MRCrv -> Levels + (MRCrv -> RefineLevel != FALSE); i++)
  520.     CagdCrvFree(MRCrv -> HieCrv[i]);
  521.  
  522.     IritFree((VoidPtr) (MRCrv -> HieCrv));
  523.     IritFree((VoidPtr) MRCrv);
  524. }
  525.  
  526. /*****************************************************************************
  527. * DESCRIPTION:                                                               M
  528. * Allocates a data structure for multi resolution decomposition of a Bspline M
  529. * curve of Levels levels and possiblt periodic.                     M
  530. *                                                                            *
  531. * PARAMETERS:                                                                M
  532. *   Levels:      Number of levels to expect in the decomposition.            M
  533. *   Periodic:    Is the curve periodic?                                      M
  534. *                                                                            *
  535. * RETURN VALUE:                                                              M
  536. *   SymbMultiResCrvStruct *:   A structure to hold a multi resolution        M
  537. *                              decomposition of a curve of Levels levels.    M
  538. *                                                                            *
  539. * KEYWORDS:                                                                  M
  540. *   SymbCrvMultiResNew, multi resolution, least square decomposition         M
  541. *****************************************************************************/
  542. SymbMultiResCrvStruct *SymbCrvMultiResNew(int Levels, CagdBType Periodic)
  543. {
  544.     SymbMultiResCrvStruct
  545.     *MRCrv = (SymbMultiResCrvStruct *)
  546.                      IritMalloc(sizeof(SymbMultiResCrvStruct));
  547.  
  548.     MRCrv -> Levels = Levels;
  549.  
  550.     /* Keep one more level for the refining level to come. */
  551.     MRCrv -> HieCrv = (CagdCrvStruct **)
  552.     IritMalloc(sizeof(CagdCrvStruct *) * (Levels + 1));
  553.  
  554.     MRCrv -> RefineLevel = FALSE;
  555.     MRCrv -> Periodic = Periodic;
  556.     MRCrv -> Pnext = NULL;
  557.  
  558.     return MRCrv;
  559. }
  560. /*****************************************************************************
  561. * DESCRIPTION:                                                               M
  562. * Given a multi resolution decomposition of a Bspline curve, copy it.        M
  563. *                                                                            *
  564. * PARAMETERS:                                                                M
  565. *   MRCrv:       A multi resolution decomposition of a curve to copy.        M
  566. *                                                                            *
  567. * RETURN VALUE:                                                              M
  568. *   SymbMultiResCrvStruct *:   A duplicated structure of MRCrv.             M
  569. *                                                                            *
  570. * KEYWORDS:                                                                  M
  571. *   SymbCrvMultiResCopy, multi resolution, least square decomposition         M
  572. *****************************************************************************/
  573. SymbMultiResCrvStruct *SymbCrvMultiResCopy(SymbMultiResCrvStruct *MRCrvOrig)
  574. {
  575.     int i;
  576.     SymbMultiResCrvStruct
  577.     *MRCrv = (SymbMultiResCrvStruct *)
  578.                      IritMalloc(sizeof(SymbMultiResCrvStruct));
  579.  
  580.     MRCrv -> Levels = MRCrvOrig -> Levels;
  581.     MRCrv -> RefineLevel = MRCrvOrig -> RefineLevel;
  582.     MRCrv -> Pnext = NULL;
  583.     MRCrv -> HieCrv = (CagdCrvStruct **) IritMalloc(sizeof(CagdCrvStruct *) *
  584.                             (MRCrvOrig -> Levels + 1));
  585.  
  586.     for (i = 0; i < MRCrv -> Levels + (MRCrv -> RefineLevel != FALSE); i++)
  587.     MRCrv -> HieCrv[i] = CagdCrvCopy(MRCrvOrig -> HieCrv[i]);
  588.  
  589.  
  590.     return MRCrv;
  591. }
  592.